package com.itcast.activiti.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itcast.activiti.constant.DataFromConstant;
import com.itcast.activiti.constant.GroupTypeConstant;
import com.itcast.activiti.domain.ApproveDefinitionSave;
import com.itcast.activiti.entity.ApproveDefinition;
import com.itcast.activiti.entity.ApproveDefinitionHistory;
import com.itcast.activiti.mapper.ApproveDefinitionMapper;
import com.itcast.activiti.service.ApproveJsonService;
import com.itcast.activiti.service.IApproveDefinitionHistoryService;
import com.itcast.activiti.service.IApproveDefinitionService;
import com.itcast.activiti.service.IDeployRepositoryService;
import com.itcast.activiti.utils.ItcastPage;
import com.itcast.activiti.utils.UUIDUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 审批定义表  服务实现类
 * </p>
 *
 * @author itcast
 * @since 2021-02-25
 */
@Service
public class ApproveDefinitionServiceImpl extends ServiceImpl<ApproveDefinitionMapper, ApproveDefinition> implements IApproveDefinitionService {
    @Autowired
    private ApproveJsonService approveJsonService;
    @Autowired
    private IDeployRepositoryService IDeployRepositoryService;
    @Autowired
    private IApproveDefinitionHistoryService iApproveDefinitionHistoryService;

    @Override
    public ApproveDefinitionSave saveApproveDefinitionReturnSave(ApproveDefinitionSave in) {
        ApproveDefinition definition = null;
        // 新增的情况下
        if (StringUtils.isEmpty(in.getBaseData().getId())) {
            definition = insertApproveDefinition(in);
        } else {
            definition = updateApproveDefinition(in);
        }
        Assert.notNull(definition, "部署失败");
        ApproveDefinitionSave save = new ApproveDefinitionSave();
        // 基础信息
        // allowUserJson 单独解析
        definition.setUserRange(approveJsonService.allowUserJsonStrToList(in.getUserRange()));
        save.setBaseData(definition);
        // 流程设计
        save.setFlowData(JSONObject.parseArray(definition.getFlowJson()));
        return save;
    }

    // 新增审批定义
    private ApproveDefinition insertApproveDefinition(ApproveDefinitionSave in) {
        ApproveDefinition approveDefinition = in.getBaseData();
        Assert.notNull(approveDefinition, "baseData is empty");
        approveDefinition.setId(UUIDUtils.randomUuid());
        Assert.hasText(approveDefinition.getTenantId(), "tenantId is empty");
        Assert.hasText(approveDefinition.getName(), "name is empty");
        // 谁可以发起这个审批json
        if (in.getUserRange() != null && in.getUserRange().size() != 0) {
            approveDefinition.setUserRange(JSON.toJSONString(in.getUserRange()));
        }
        // 流程json
        approveDefinition.setFlowJson(approveJsonService.parseFlowJson(in.getFlowData()));
        approveDefinition.setFlowDataJson(in.getFlowDataJson());
        // 数据来源-新增
        approveDefinition.setDataFrom(DataFromConstant.INSERT);
        if (approveDefinition.getGroupType() == null) {
            approveDefinition.setGroupType(GroupTypeConstant.OTHER);
        }
        // 插入数据
        int insert = baseMapper.insert(approveDefinition);
        if (insert == 0) {
            throw new RuntimeException("create approveDefinition failure");
        }
        // 工作流中新建流程定义
        String deploymentId = IDeployRepositoryService.createDeploymentJson(approveDefinition);
        iApproveDefinitionHistoryService.insertApproveDefinitionHistory(approveDefinition, deploymentId);
        return approveDefinition;
    }

    // 编辑审批定义
    private ApproveDefinition updateApproveDefinition(ApproveDefinitionSave in) {
        String id = in.getBaseData().getId();
        ApproveDefinitionHistory approveDefinitionHistory = iApproveDefinitionHistoryService.getApproveDefinitionHistory(Integer.parseInt(id));
        if (approveDefinitionHistory == null) throw new RuntimeException("依据ID为获取到审批流程定义信息失败：" + id);
        ApproveDefinition approveDefinition = getApproveDefinition(approveDefinitionHistory.getApproveDefinitionId());
        if (approveDefinition == null) throw new RuntimeException("依据ID为获取到审批流程定义信息失败：" + id);
        // 要更新的内容赋值
        BeanUtils.copyProperties(in.getBaseData(), approveDefinition, "id", "userRange");
        // 谁可以发起这个审批json
        if (in.getUserRange() != null && in.getUserRange().size() != 0) {
            approveDefinition.setUserRange(JSON.toJSONString(in.getUserRange()));
        }
        // 流程json
        approveDefinition.setFlowJson(approveJsonService.parseFlowJson(in.getFlowData()));
        approveDefinition.setFlowDataJson(in.getFlowDataJson());
        // 插入数据
        int insert = baseMapper.updateById(approveDefinition);
        if (insert == 0) {
            throw new RuntimeException("update approveDefinition failure");
        }
        // 工作流中更新流程定义
        String deploymentId = IDeployRepositoryService.createDeploymentJson(approveDefinition);
        iApproveDefinitionHistoryService.insertApproveDefinitionHistory(approveDefinition, deploymentId);
        return approveDefinition;
    }


    @Override
    public ApproveDefinition getApproveDefinition(String id) {
        return baseMapper.selectById(id);
    }

    @Override
    public ItcastPage listApproveDefinitionPage(ItcastPage itcastPage) {
        JSONObject condition = itcastPage.getCondition();
        QueryWrapper<ApproveDefinition> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(condition.getString(ApproveDefinition.Fields.name))) {
            queryWrapper.lambda().like(ApproveDefinition::getName, condition.getString(ApproveDefinition.Fields.name));
        }
        queryWrapper.lambda().eq(ApproveDefinition::getDeleted, false);
        return baseMapper.selectPage(itcastPage, queryWrapper);
    }

    @Override
    public ApproveDefinition getApproveDefinitionByDefinitionIdAndTenantId(String definitionId, String tenantId) {
        ApproveDefinition approveDefinition = baseMapper.selectById(definitionId);
        if (approveDefinition.getTenantId().equals(tenantId)) {
            return approveDefinition;
        }
        ApproveDefinitionHistory approveDefinitionHistory = iApproveDefinitionHistoryService.getLastDefinitionByByDefinitionIdAndTenantId(definitionId, tenantId);
        ApproveDefinition approveDefinitionHis = new ApproveDefinition();
        BeanUtils.copyProperties(approveDefinitionHistory,approveDefinitionHis);
        return approveDefinitionHis;
    }
}
